import { defineStore } from "pinia";
import type { AppRouteRecordRaw, Menu } from "@/router/types";

import { PERMISSION_STORE } from "../modulesName";
import { getUserPermissionByToken } from "@/api/sys/user.api";
import { camelCase, cloneDeep, flowRight, get, upperFirst } from "lodash-es";
import { transformToRoute } from "@/router/helper/route.helper";
import { h } from "vue";
import { NIcon } from "naive-ui";

// 预加载常用图标组件以提高性能
import * as AntdIcons from "@vicons/antd";

// 定义一个函数来获取图标组件
function getIconComponent(iconName: string): any {
  try {
    // 直接从预加载的图标中获取
    if (AntdIcons[iconName]) {
      return AntdIcons[iconName];
    }
    // 如果找不到图标，返回默认图标
    console.warn(`图标 "${iconName}" 未找到，使用默认图标代替。`);
    return AntdIcons.HomeFilled;
  } catch (error) {
    console.warn(`获取图标时出错: ${error}`);
    return AntdIcons.HomeFilled;
  }
}

// 系统权限
interface AuthItem {
  // 菜单权限编码，例如："sys:schedule:list,sys:schedule:info",多个逗号隔开
  action: string;
  // 权限策略1显示2禁用
  type: string | number;
  // 权限状态(0无效1有效)
  status: string | number;
  // 权限名称
  describe?: string;
  isAuth?: boolean;
}

interface PermissionState {
  // Permission code list
  permCodeList: string[] | number[];
  // Whether the route has been dynamically added
  isDynamicAddedRoute: boolean;
  // To trigger a menu update
  lastBuildMenuTime: number;
  // Backstage menu list
  backMenuList: Menu[];
  frontMenuList: Menu[];
  // 用户所拥有的权限
  authList: AuthItem[];
  // 全部权限配置
  allAuthList: AuthItem[];
  // 系统安全模式
  sysSafeMode: boolean;
  // online子表按钮权限
  onlineSubTableAuthMap: Recordable;
  // 需要缓存的组件名称列表
  cachedViews: string[];
}

export const usePermissionStore = defineStore({
  id: PERMISSION_STORE,
  state: (): PermissionState => ({
    permCodeList: [],
    // Whether the route has been dynamically added
    isDynamicAddedRoute: false,
    // To trigger a menu update
    lastBuildMenuTime: 0,
    // Backstage menu list
    backMenuList: [],
    // menu List
    frontMenuList: [],
    authList: [],
    allAuthList: [],
    sysSafeMode: false,
    onlineSubTableAuthMap: {},
    // 需要缓存的组件名称列表
    cachedViews: [],
  }),
  getters: {
    getPermCodeList(): string[] | number[] {
      return this.permCodeList;
    },
    getBackMenuList(): Menu[] {
      return this.backMenuList;
    },
    getFrontMenuList(): Menu[] {
      return this.frontMenuList;
    },
    getLastBuildMenuTime(): number {
      return this.lastBuildMenuTime;
    },
    getIsDynamicAddedRoute(): boolean {
      return this.isDynamicAddedRoute;
    },
    getOnlineSubTableAuth: (state) => {
      return (code: any) => state.onlineSubTableAuthMap[code];
    },
    // 获取需要缓存的组件名称列表
    getCachedViews(): string[] {
      return this.cachedViews;
    },
  },
  actions: {
    setBackMenuList(list: Menu[]) {
      this.backMenuList = list;
      list?.length > 0 && this.setLastBuildMenuTime();
    },
    setLastBuildMenuTime() {
      this.lastBuildMenuTime = new Date().getTime();
    },
    setDynamicAddedRoute(added: boolean) {
      this.isDynamicAddedRoute = added;
    },
    setPermCodeList(codeList: string[]) {
      this.permCodeList = codeList;
    },
    setAuthData(systemPermission: any) {
      this.authList = systemPermission.auth;
      this.allAuthList = systemPermission.allAuth;
      this.sysSafeMode = systemPermission.sysSafeMode;
    },
    // 添加需要缓存的组件
    addCachedView(componentName: string) {
      if (componentName && !this.cachedViews.includes(componentName)) {
        this.cachedViews.push(componentName);
      }
    },
    // 移除缓存的组件
    removeCachedView(componentName: string) {
      const index = this.cachedViews.indexOf(componentName);
      if (index > -1) {
        this.cachedViews.splice(index, 1);
      }
    },
    // 从路由列表中提取需要缓存的组件
    extractCachedViews(routes: any[]) {
      const extractComponentNames = (routeList: any[]) => {
        routeList.forEach(route => {
          if (route.meta?.keepAlive && route.meta?.componentName) {
            this.addCachedView(route.meta.componentName);
          }
          if (route.children && route.children.length > 0) {
            extractComponentNames(route.children);
          }
        });
      };
      
      extractComponentNames(routes);
    },
    async changePermissionCode() {
      const res: any = await getUserPermissionByToken();
      const systemPermission = get(res, "result") || {};
      const codeList = systemPermission.codeList;
      this.setPermCodeList(codeList);
      this.setAuthData(systemPermission);

      //菜单路由
      const routeList = systemPermission.menu;
      return routeList;
    },

    async buildRoutesAction() {
      let routes: AppRouteRecordRaw[] = [];

      console.log(" --- 构建后台路由菜单 --- ");
      let routeList: AppRouteRecordRaw[] = [];
      try {
        routeList = await this.changePermissionCode();
      } catch (err) {
        console.error(err);
      }

      // 优化检查逻辑，减少不必要的循环
      const _addIconToRoutes = (routes: any[]) => {
        let updatedRoutes = [];
        let routesClone = cloneDeep(routes);

        for (let i = 0; i < routesClone.length; i++) {
          const route = routesClone[i];
          if (!route.meta) route.meta = {};

          // 处理图标
          if (route.meta.icon) {
            let iconStr = get(route, "meta.icon") || "";
            // 优化图标字符串解析
            
            if (iconStr) {
              iconStr = flowRight([upperFirst, camelCase])(iconStr);
              const IconComponent = getIconComponent(iconStr);

              // 创建图标渲染函数
              route.icon = () =>
                h(NIcon, null, { default: () => h(IconComponent) });
            } else {}
          }

          // 递归处理子路由
          if (route.children && route.children.length > 0) {
            route.children = _addIconToRoutes(route.children);
          }

          updatedRoutes.push(route);
        }

        return updatedRoutes;
      };

      let _menuList = cloneDeep(routeList);
      _menuList = _addIconToRoutes(_menuList);
      routeList = transformToRoute(routeList);
      
      // 提取需要缓存的组件
      this.extractCachedViews(routeList);

      this.setBackMenuList(_menuList);
      return routeList;
    },
  },
});
